#include "include.h"
#include <stdio.h>

static bool fUartRxComplete = FALSE;
static uint8 UartRxBuffer[260];
uint8 Uart1RxBuffer[260];

// static bool UartBusy = FALSE;

uint8  frameIndexSumSum[256];

int fputc(int ch, FILE *f);     //fputc重定向



int fputc(int ch, FILE *f)
{
  
   USART_SendData(USART1, (u8) ch);

  
   while(!(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == SET))
   {
   }

   return ch;
}



void InitUart1(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
//	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);//时钟使能
	//USART1_TX   PA.9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	//USART1_RX	  PA.10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	//USART 初始化设置

	USART_InitStructure.USART_BaudRate = 115200;//一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

	USART_Init(USART1, &USART_InitStructure);

	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断

	USART_Cmd(USART1, ENABLE);                    //使能串口
	
	
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器USART1
}

void Uart1SendData(BYTE dat)
{
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
	USART1->DR = (u8) dat;
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
}

void UART1SendDataPacket(uint8 dat[],uint8 count)
{
	uint32 i;
	for(i = 0; i < count; i++)
	{
//		USART1_TransmitData(tx[i]);
		while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
		USART1->DR = dat[i];
		while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
	}
}

/**************************************************************************
函数功能：串口3接收中断（与串口1中断互换）
入口参数：无
返回  值：无
**************************************************************************/
void USART1_IRQHandler(void)
{	  
	uint8 i;
	uint8 rxBuf;

	static uint8 startCodeSum = 0;
	static bool fFrameStart = FALSE;
	static uint8 messageLength = 0;
	static uint8 messageLengthSum = 2;

	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
	{
		rxBuf =USART_ReceiveData(USART1);//(USART1->DR);	//读取接收到的数据
		//USART_SendData(USART1,Res);
		UART1_Receive(rxBuf);	
		if(!fFrameStart)//没读到指令部分，还在帧头或别的地方
		{
			if(rxBuf == 0x55)
			{

				startCodeSum++;
				if(startCodeSum == 2)//接收到两个0x55帧头
				{
					startCodeSum = 0;//指令部分的长度开始累加
					fFrameStart = TRUE;//接下来是指令部分
					messageLength = 1;//指令部分指针（数组下标）
				}
			}
			else//没能完整接收到两个帧头的情况下
			{
				//全部参数初始化
				fFrameStart = FALSE;
				messageLength = 0;
	
				startCodeSum = 0;
			}
			
		}
		if(fFrameStart)//开始读取指令部分
		{
			Uart1RxBuffer[messageLength] = rxBuf;//Uart1RxBuffer[1] = 0x55 第零位没存，其实对应第一个帧头0x55，Uart1RxBuffer就是把接受到的数据统一又存了一遍
			if(messageLength == 2)//第三位为除去两帧头的长度messageLengthSum
			{
				messageLengthSum = Uart1RxBuffer[messageLength];
				if(messageLengthSum < 2)// || messageLengthSum > 30 //除去两帧头的数据在包含一个长度[3]和最少一指令[4]的情况下肯定大于2，异常则退出
				{
					messageLengthSum = 2;
					fFrameStart = FALSE;
					
				}
					
			}
			messageLength++;
	
			if(messageLength == messageLengthSum + 2) //这是指处理到最后一个数据了 下标=除去两帧头+2
			{
				if(fUartRxComplete == FALSE)//还没处理完接收的数据
				{
					fUartRxComplete = TRUE;//现在接受完了
					for(i = 0;i < messageLength;i++)//把接收的数据换了个地方存
					{
						UartRxBuffer[i] = Uart1RxBuffer[i];
					}
				}
				

				fFrameStart = FALSE;//没进入上一个if就是接受的数据还没处理完
			}
		}
	}			
} 

void USART3_IRQHandler(void)
{
	uint8 i;
	uint8 rxBuf;

	static uint8 startCodeSum = 0;
	static bool fFrameStart = FALSE;
	static uint8 messageLength = 0;
	static uint8 messageLengthSum = 2;
	
	//接收中断
	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
	{
		rxBuf = USART_ReceiveData(USART3);//(USART1->DR);	//读取接收到的数据,存储在静态变量rxBuf中
		//USART_SendData(USART3,rxBuf);
		UART3_Receive(rxBuf);	
		if(!fFrameStart)//没读到指令部分，还在帧头或别的地方
		{
			if(rxBuf == 0x55)
			{

				startCodeSum++;
				if(startCodeSum == 2)//接收到两个0x55帧头
				{
					startCodeSum = 0;//指令部分的长度开始累加
					fFrameStart = TRUE;//接下来是指令部分
					messageLength = 1;//指令部分指针（数组下标）
				}
			}
			else//没能完整接收到两个帧头的情况下
			{
				//全部参数初始化
				fFrameStart = FALSE;
				messageLength = 0;
	
				startCodeSum = 0;
			}
			
		}
		if(fFrameStart)//开始读取指令部分
		{
			Uart1RxBuffer[messageLength] = rxBuf;//Uart1RxBuffer[1] = 0x55 第零位没存，其实对应第一个帧头0x55，Uart1RxBuffer就是把接受到的数据统一又存了一遍
			if(messageLength == 2)//第三位为除去两帧头的长度messageLengthSum
			{
				messageLengthSum = Uart1RxBuffer[messageLength];
				if(messageLengthSum < 2)// || messageLengthSum > 30 //除去两帧头的数据在包含一个长度[3]和最少一指令[4]的情况下肯定大于2，异常则退出
				{
					messageLengthSum = 2;
					fFrameStart = FALSE;
					
				}
					
			}
			messageLength++;
	
			if(messageLength == messageLengthSum + 2) //这是指处理到最后一个数据了 下标=除去两帧头+2
			{
				if(fUartRxComplete == FALSE)//还没处理完接收的数据
				{
					fUartRxComplete = TRUE;//现在接受完了
					for(i = 0;i < messageLength;i++)//把接收的数据换了个地方存
					{
						UartRxBuffer[i] = Uart1RxBuffer[i];
					}
				}
				

				fFrameStart = FALSE;//没进入上一个if就是接受的数据还没处理完
			}
		}
	}
}

//单片机给PC传数据
void McuToPCSendData(uint8 cmd,uint8 prm1,uint8 prm2)
{
	uint8 dat[8];
	uint8 datlLen = 2;
	switch(cmd)
	{

//		case CMD_ACTION_DOWNLOAD:
//			datlLen = 2;
//			break;

		default:
			datlLen = 2;
			break;
	}

	dat[0] = 0x55;
	dat[1] = 0x55;
	dat[2] = datlLen;
	dat[3] = cmd;
	dat[4] = prm1;
	dat[5] = prm2;
	UART1SendDataPacket(dat,datlLen + 2);
}

//判断接收完成没有
static bool UartRxOK(void)
{
	if(fUartRxComplete)
	{
		fUartRxComplete = FALSE;
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
void FlashEraseAll(void);
void SaveAct(uint8 fullActNum,uint8 frameIndexSum,uint8 frameIndex,uint8* pBuffer);

//根据接收的数据，调用下面的函数做 出不同的操作
void TaskPCMsgHandle(void)
{

	uint16 i;
	uint8 cmd;
	uint8 id;
	uint8 servoCount;
	uint16 time;
	uint16 pos;
	uint16 times;
	uint8 fullActNum;
	if(UartRxOK()) //判断接收完成没有
	{
		LED = !LED;
		cmd = UartRxBuffer[3];//除去两帧头的长度messageLengthSum
 		switch(cmd)//根据长度判断指令类型
 		{
 			case CMD_MULT_SERVO_MOVE: //多个舵机相同时间运动
				servoCount = UartRxBuffer[4]; //舵机个数
				time = UartRxBuffer[5] + (UartRxBuffer[6]<<8);//运动时间即速度
				for(i = 0; i < servoCount; i++)
				{
					id =  UartRxBuffer[7 + i * 3];
					pos = UartRxBuffer[8 + i * 3] + (UartRxBuffer[9 + i * 3]<<8);
	
					ServoSetPluseAndTime(id,pos,time);//设置舵机转动的目标位置和转动时间
					//BusServoCtrl(id,SERVO_MOVE_TIME_WRITE,pos,time);                                  //总线舵机，不用
				}
 				break;
			
			case CMD_FULL_ACTION_RUN://运行动作组
				fullActNum = UartRxBuffer[4];//动作组编号
				times = UartRxBuffer[5] + (UartRxBuffer[6]<<8);//运行次数
				FullActRun(fullActNum,times);
				break;
				
			case CMD_FULL_ACTION_STOP://停止运行动作组
				FullActStop();
				break;
				
			case CMD_FULL_ACTION_ERASE://动作组擦除
				FlashEraseAll();
				McuToPCSendData(CMD_FULL_ACTION_ERASE,0,0);
				break;

			case CMD_ACTION_DOWNLOAD://下载动作组
				SaveAct(UartRxBuffer[4],UartRxBuffer[5],UartRxBuffer[6],UartRxBuffer + 7);
				McuToPCSendData(CMD_ACTION_DOWNLOAD,0,0);
				break;
 		}
	}
}
void SaveAct(uint8 fullActNum,uint8 frameIndexSum,uint8 frameIndex,uint8* pBuffer)
{
	uint8 i;
	
	if(frameIndex == 0)//下载之前先把这个动作组擦除
	{//一个动作组占16k大小，擦除一个扇区是4k，所以要擦4次
		for(i = 0;i < 4;i++)//ACT_SUB_FRAME_SIZE/4096 = 4
		{
			FlashEraseSector((MEM_ACT_FULL_BASE) + (fullActNum * ACT_FULL_SIZE) + (i * 4096));
		}
	}

	FlashWrite((MEM_ACT_FULL_BASE) + (fullActNum * ACT_FULL_SIZE) + (frameIndex * ACT_SUB_FRAME_SIZE)
		,ACT_SUB_FRAME_SIZE,pBuffer);
	
	if((frameIndex + 1) ==  frameIndexSum)
	{
		FlashRead(MEM_FRAME_INDEX_SUM_BASE,256,frameIndexSumSum);
		frameIndexSumSum[fullActNum] = frameIndexSum;
		FlashEraseSector(MEM_FRAME_INDEX_SUM_BASE);
		FlashWrite(MEM_FRAME_INDEX_SUM_BASE,256,frameIndexSumSum);
	}
}


void FlashEraseAll(void)
{//将所有255个动作组的动作数设置为0，即代表将所有动作组擦除
	uint16 i;
	
	for(i = 0;i <= 255;i++)
	{
		frameIndexSumSum[i] = 0;
	}
	FlashEraseSector(MEM_FRAME_INDEX_SUM_BASE);
	FlashWrite(MEM_FRAME_INDEX_SUM_BASE,256,frameIndexSumSum);
}

void InitMemory(void)
{
	uint8 i;
	uint8 logo[] = "LOBOT";
	uint8 datatemp[8];

	FlashRead(MEM_LOBOT_LOGO_BASE,5,datatemp);
	for(i = 0; i < 5; i++)
	{
		if(logo[i] != datatemp[i])
		{
		LED = LED_ON;
			//如果发现不相等的，则说明是新FLASH，需要初始化
			FlashEraseSector(MEM_LOBOT_LOGO_BASE);
			FlashWrite(MEM_LOBOT_LOGO_BASE,5,logo);
			FlashEraseAll();
			break;
		}
	}
	
}



